package ProjectCodeEngine;

import CodeProcess.DiameterProcess;
import CodeProcess.DrivepipeProcess;
import CodeProcess.PositionProcess;
import CodeProcess.ProjectCodeProcess;
import CodeProcess.SpecimenProcess;
import CodeProcess.Z4DiameterProcess;
import CodeProcess.Z4ThicknessProcess;
import model.EvaluationResult;
import model.SkillEvaluation;
import model.TranslateResult;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 手工焊解析器
 *
 * @author zzy
 * @version V1.0
 * @since 2022/8/1
 */
public class ParseManualWelding implements ParseProjectCode {

    public EvaluationResult parse(String[] args, String type) {
        EvaluationResult evaluationResult = new EvaluationResult();

        // 焊接位置下标
        int index = ProjectCodeProcess.getPositionIndex(args);

        // 是否为特殊金属焊缝
        String specialElement = ProjectCodeProcess.getSpecialElement(args);

        // 3.1 焊接方法
        evaluationResult.setWeldMethod(getWeldMethod(args[0], type).getWeldMethod());

        // 3.2 试件形式
        evaluationResult.setSpecimen(getSpecimen(args).getSpecimen());

        // 3.3 焊缝形式
        evaluationResult.setGap(getGap(args[2]).getGap());

        // 3.4 填充材料
        evaluationResult.setMaterial(getMaterial(args[3]).getMaterial());

        // 3.5 焊接位置
        evaluationResult.setPosition(getPosition(args, index).getPosition());

        // 处理特殊焊缝
        if (specialElement != null) {

            // 管的承插焊 Z4
            if ("Z4".equals(specialElement)) {
                EvaluationResult thickness = handleZ4Thickness(args, index);
                evaluationResult.setThickness(thickness.getThickness());

                EvaluationResult diameter = handleZ4Diameter(args, index);
                evaluationResult.setDiameter(diameter.getDiameter());
            }

        }
        // 3.6 焊缝金属厚度和管外径
        else {
            EvaluationResult thickness = getThickness(args, index);
            evaluationResult.setThickness(thickness.getThickness());
            // 处理套管
            if (thickness.getOutThickness() != null) {
                evaluationResult.setOutThickness(thickness.getOutThickness());
            }

            EvaluationResult diameterResult = getDiameter(args, index);
            if (diameterResult != null) {
                evaluationResult.setDiameter(diameterResult.getDiameter());
            }
        }

        // 3.7 焊接要素
        evaluationResult.setElement(getElements(args, index).getElement());

        System.out.println(evaluationResult.toString());

        return evaluationResult;
    }

    /**
     * Z4承插焊的Thickness处理
     *
     * @param args
     * @param index
     * @return
     */
    private EvaluationResult handleZ4Thickness(String[] args, int index) {
        EvaluationResult result = new EvaluationResult();
        Z4ThicknessProcess z4 = new Z4ThicknessProcess();

        int thickness = 4;
        if (index == 0) {

        }
        String params = args[thickness];
        TranslateResult translateResult = new TranslateResult(
                z4.process(args),
                z4.processName(params),
                z4.processMeaning(params),
                z4.processSuit(params)
        );
        result.setThickness(translateResult);
        return result;
    }

    /**
     * Z4承插焊的Diameter处理
     *
     * @param args
     * @param index
     * @return
     */
    private EvaluationResult handleZ4Diameter(String[] args, int index) {
        EvaluationResult result = new EvaluationResult();
        Z4DiameterProcess z4 = new Z4DiameterProcess();

        if (index == 0) {

        }
        else {
            int diameter = index - 1;
            String params = args[diameter];
            TranslateResult translateResult = new TranslateResult(
                    z4.process(args),
                    z4.processName(params),
                    z4.processMeaning(params),
                    z4.processSuit(params)
            );
            result.setDiameter(translateResult);
        }
        return result;
    }

    /**
     * 3.7 焊接要素
     *
     * @param args
     * @param index
     * @return
     */
    private EvaluationResult getElements(String[] args, int index) {
        int flag = index == 0 ? 5 : index;
        List<String> list = new ArrayList<String>(Arrays.asList(args).subList(flag + 1, args.length));
        SkillEvaluation skillEvaluation = new SkillEvaluation();
        skillEvaluation.setElement(list);
        return getINSTANSE(skillEvaluation, new EvaluationResult());
    }

    /**
     * 3.6 管外径 D
     *
     * @param args
     * @param index
     * @return
     */
    private EvaluationResult getDiameter(String[] args, int index) {
        SkillEvaluation skillEvaluation = new SkillEvaluation();

        if ("T-T".equals(args[1])) {
            Float[] params = ProjectCodeProcess.pipeLineT_THandler(args[index - 1]);

            EvaluationResult result = new EvaluationResult();
            DiameterProcess p = new DiameterProcess();

            TranslateResult translateResult = new TranslateResult(
                    p.process(args),
                    p.processName(params),
                    p.processMeaning(params),
                    p.processSuit(params)
            );

            result.setDiameter(translateResult);
            return result;
        }
        // 走T的代码
        else if ("P".equals(args[1]) && "FW".equals(args[2])) {
            // 没有D直径
            if (index != 0) {
                Float[] params = ProjectCodeProcess.pipeLineP_T_FWHandler(args[index - 1]);
                skillEvaluation.setDiameter(params[1]);
                return getEvaluationResult(args, skillEvaluation);
            } else {
                return null;
            }
        }
        // P-T FW
        else if ("P-T".equals(args[1]) && "FW".equals(args[2])) {
            Float[] params = ProjectCodeProcess.pipeLineP_T_FWHandler(args[index - 1]);
            skillEvaluation.setDiameter(params[1]);
            return getEvaluationResult(args, skillEvaluation);
        }
        // 走t的代码
        else if ("P-T".equals(args[1])) {
            Float[] params = ProjectCodeProcess.pipeLineP_THandler(args[index - 1]);
            skillEvaluation.setDiameter(params[1]);
            return getEvaluationResult(args, skillEvaluation);
        }
        // 没有直径D
        else if (index != 0) {
            // 走套管的代码
            if (ProjectCodeProcess.isDrivepipe(args[index - 1])) {
                Float[] params = ProjectCodeProcess.pipeLineT_D_THandler(args[index - 1]);
                return DrivepipeProcess.doDrivepipeDiameter(params[1]);
            }
            // 默认类型
            else {
                skillEvaluation.setDiameter(Float.valueOf(args[index - 1].substring(1)));
                return getEvaluationResult(args, skillEvaluation);
            }
        }
        // 无
        else {
            return null;
        }
    }

    /**
     * 3.6 焊缝金属厚度 T
     *
     * @param args
     * @param index
     * @return
     */
    private EvaluationResult getThickness(String[] args, int index) {
        SkillEvaluation skillEvaluation = new SkillEvaluation();
        int thickness = 4;

        if ("T-T".equals(args[1])) {
            Float[] params = ProjectCodeProcess.pipeLineT_THandler(args[index - 1]);
            skillEvaluation.setThickness(params[0]);
        }
        // 走T的代码
        else if ("P".equals(args[1]) && "FW".equals(args[2])) {
            // 没有D直径
            if (index == 0) {
                skillEvaluation.setThickness(Float.valueOf(args[thickness].substring(1)));
                skillEvaluation.setGap(args[2]);
                skillEvaluation.setSpecimen(args[1]);
            } else {
                Float[] params = ProjectCodeProcess.pipeLineP_T_FWHandler(args[index - 1]);
                skillEvaluation.setThickness(params[0]);
            }
        }
        // P-T FW
        else if ("P-T".equals(args[1]) && "FW".equals(args[2])) {
            Float[] params = ProjectCodeProcess.pipeLineP_T_FWHandler(args[index - 1]);
            skillEvaluation.setThickness(params[0]);
            skillEvaluation.setGap(args[2]);
            skillEvaluation.setSpecimen(args[1]);
        }
        // 走t的代码
        else if ("P-T".equals(args[1])) {
            Float[] params = ProjectCodeProcess.pipeLineP_THandler(args[index - 1]);
            skillEvaluation.setThickness(params[0]);
        }
        // 走套管的代码
        else if (index != 0) {
            if (ProjectCodeProcess.isDrivepipe(args[index - 1])) {
                Float[] params = ProjectCodeProcess.pipeLineT_D_THandler(args[index - 1]);
                return DrivepipeProcess.doDrivepipeThinkness(params[0], params[2]);
            }
            // 默认类型
            else {
                skillEvaluation.setThickness(Float.valueOf(args[thickness].substring(1)));
                skillEvaluation.setGap(args[2]);
            }
        }
        // 默认类型
        else {
            skillEvaluation.setThickness(Float.valueOf(args[thickness].substring(1)));
            skillEvaluation.setGap(args[2]);
        }

        return getINSTANSE(skillEvaluation, new EvaluationResult());
    }

    /**
     * 3.5 焊接位置
     *
     * @param args
     * @param index
     * @return
     */
    private EvaluationResult getPosition(String[] args, int index) {
        SkillEvaluation skillEvaluation = new SkillEvaluation();
        int flag = index == 0 ? 5 : index;
        skillEvaluation.setPosition(args[flag]);
        EvaluationResult result = getINSTANSE(skillEvaluation, new EvaluationResult());
        TranslateResult oldPosition = result.getPosition();

        PositionProcess p = new PositionProcess();
        String suit = oldPosition.getSuit() + p.process(args);
        oldPosition.setSuit(suit);
        result.setPosition(oldPosition);
        return result;
    }

    /**
     * 3.4 填充材料
     *
     * @param material
     * @return
     */
    private EvaluationResult getMaterial(String material) {
        SkillEvaluation skillEvaluation = new SkillEvaluation();
        skillEvaluation.setMaterial(material);
        EvaluationResult result = getINSTANSE(skillEvaluation, new EvaluationResult());
        TranslateResult oldMaterial = result.getMaterial();
        TranslateResult oldCoating = result.getCoating();

        // 拼接焊接方法属性额外信息
        if (oldCoating != null) {
            oldMaterial.setName(material);
            oldMaterial.setMeaning(oldMaterial.getMeaning() + "\t药皮类型：" + oldCoating.getMeaning());
            oldMaterial.setSuit(oldMaterial.getSuit() + "\t药皮类型：" + oldCoating.getSuit());
        }

        result.setMaterial(oldMaterial);
        return result;
    }

    /**
     * 3.3 焊缝形式
     *
     * @param gap
     * @return
     */
    private EvaluationResult getGap(String gap) {
        SkillEvaluation skillEvaluation = new SkillEvaluation();
        skillEvaluation.setGap(gap);
        return getINSTANSE(skillEvaluation, new EvaluationResult());
    }

    /**
     * 3.2 试件形式
     *
     * @param args
     * @return
     */
    private EvaluationResult getSpecimen(String[] args) {
        SkillEvaluation skillEvaluation = new SkillEvaluation();
        skillEvaluation.setSpecimen(args[1]);
        skillEvaluation.setGap(args[2]);
        EvaluationResult result = getINSTANSE(skillEvaluation, new EvaluationResult());
        TranslateResult oldSpecimen = result.getSpecimen();

        SpecimenProcess p = new SpecimenProcess();
        String suit = oldSpecimen.getSuit() + p.process(args);
        oldSpecimen.setSuit(suit);
        result.setSpecimen(oldSpecimen);
        return result;
    }

    /**
     * 3.1 焊接方法
     *
     * @param weldMethod
     * @param type
     * @return
     */
    private EvaluationResult getWeldMethod(String weldMethod, String type) {
        SkillEvaluation skillEvaluation = new SkillEvaluation();
        skillEvaluation.setWeldMethod(weldMethod);
        EvaluationResult result = getINSTANSE(skillEvaluation, new EvaluationResult());
        TranslateResult oldMethod = result.getWeldMethod();

        // 拼接焊接方法属性额外信息
        String meaning = oldMethod.getMeaning() + "\t" + type;
        String suit = oldMethod.getSuit() + "\t" + type;
        oldMethod.setMeaning(meaning);
        oldMethod.setSuit(suit);
        result.setWeldMethod(oldMethod);
        return result;
    }

    private EvaluationResult getEvaluationResult(String[] args, SkillEvaluation skillEvaluation) {
        EvaluationResult result = getINSTANSE(skillEvaluation, new EvaluationResult());
//        TranslateResult oldDiameter = result.getDiameter();
//        DiameterProcess p = new DiameterProcess();
//        oldDiameter.setType(p.process(args));
//        result.setDiameter(oldDiameter);
        return result;
    }

    private EvaluationResult getINSTANSE(SkillEvaluation skillEvaluation, EvaluationResult evaluationResult) {
        // 获取KieServices
        KieServices kieServices = KieServices.Factory.get();
        // 获取KieContainer
        KieContainer container = kieServices.getKieClasspathContainer();
        // 获取KieSession
        KieSession kieSession = container.newKieSession();

        // 插入事实对象
        kieSession.insert(skillEvaluation);
        kieSession.insert(evaluationResult);

        // 触发
        kieSession.fireAllRules();
        // 关闭
        kieSession.dispose();
        return evaluationResult;
    }
}
